home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c / 640 < prev    next >
Internet Message Format  |  1996-08-06  |  2KB

  1. Path: hubcap.clemson.edu!hubcap!mjs
  2. From: mjs@hubcap.clemson.edu (M. J. Saltzman)
  3. Newsgroups: comp.std.c
  4. Subject: Re: Restrictions on qsort compare function?
  5. Date: 21 Mar 96 14:53:18 GMT
  6. Organization: Clemson University
  7. Message-ID: <mjs.827419998@hubcap>
  8. References: <4iokop$h4p@lyra.csx.cam.ac.uk>
  9. NNTP-Posting-Host: hubcap.clemson.edu
  10. X-Newsreader: NN version 6.5.0 #1
  11.  
  12. jkb@mrc-lmb.cam.ac.uk (James Bonfield) writes:
  13.  
  14. |Are there any limitations on what the sort function passed over to qsort can
  15. |do or return? I know it's meant to return < 0, 0 or > 0 for the various
  16. |compare operations, but which you return is purely up to your own comparison
  17. |system.
  18.  
  19. |On tracking down a bug in some old code I noticed that we had the
  20. |compare function returning something like "a > b" instead of "b - a".
  21. |Now this is obviously some silly bug in our coding, but "a > b" is still
  22. |a valid sort function surely? The reason I ask is that this that such
  23. |functions appear to make the Irix 5.3 qsort() function underflow the
  24. |passed array. Please check the following function to verify that I
  25. |haven't done something daft.
  26.  
  27. As others have pointed out, b - a runs the risk of overflow if a and b
  28. are large enough in magnitude and of opposite sign.  That's why it is
  29. often recommended against as a value to return from the compare function.
  30. BTW, without overflow, b - a is positive if b > a, not if a > b.
  31.  
  32.  
  33. |#include <stdio.h>
  34. |#include <stdlib.h>
  35.  
  36. |static int sort_func(const void *pa, const void *pb)
  37. |{
  38. |    const int *a = (int *)pa;
  39. |    const int *b = (int *)pb;
  40.  
  41. |    return *a > *b;
  42. |}
  43.  
  44. This function returns either a 0 if *a <= *b or a 1 if *a > *b.  Since
  45. keys are considered equal if sort_func() returns zero, this will not
  46. properly discern a case where the first argument must appear before
  47. the second.  It would surprise me not at all if qsort() relied on
  48. sort_func() having the property that
  49.  
  50.     !!sort_func(p1, p2) == -1 * !!sort_func(p2, p1)
  51.  
  52. which does not hold for this function.  (The Standard wording seems
  53. to me to require this property, but I'm not a duly certified language
  54. lawyer...)
  55.  
  56. Try 
  57.  
  58.     static int sort_func(const void *pa, const void *pb)
  59.     {
  60.         const int *a = (int *)pa;
  61.         const int *b = (int *)pb;
  62.  
  63.         return (*a > *b) - (*a < *b);
  64.     }
  65.  
  66. instead.
  67. -- 
  68.         Matthew Saltzman
  69.         Clemson University Math Sciences
  70.         mjs@clemson.edu
  71.